package com.ruoyi.back.service.impl

import cn.hutool.core.bean.BeanUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.shaun.core.context.ProfileHolder
import com.ruoyi.app.common.*
import com.ruoyi.app.domain.dto.*
import com.ruoyi.app.domain.vo.*
import com.ruoyi.app.service.TemplateApiService
import com.ruoyi.back.domain.*
import com.ruoyi.back.domain.v3.PicTemplateFaceService
import com.ruoyi.back.domain.v3.VideoTemplateFaceService
import com.ruoyi.back.enums.CheckStatusEnum
import com.ruoyi.back.enums.MessageTypeEnum
import com.ruoyi.back.mapper.ChannelFreeTemplateMapper
import com.ruoyi.back.service.*
import com.ruoyi.socket.WebSocketServer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service

@Service
class TemplateApiServiceImpl : TemplateApiService {

    @Autowired
    private lateinit var templateService: TemplateService

    @Autowired
    private lateinit var picTemplateFaceService: PicTemplateFaceService

    @Autowired
    private lateinit var videoTemplateFaceService: VideoTemplateFaceService

    @Autowired
    private lateinit var templateCommentService: TemplateCommentService

    @Autowired
    private lateinit var templateCategoryService: TemplateCategoryService

    @Autowired
    private lateinit var templateReportService: TemplateReportService

    @Autowired
    private lateinit var userCollectService: UserCollectService

    @Autowired
    private lateinit var appUserService: AppUserService

    @Autowired
    private lateinit var userInteractionMessageService: UserInteractionMessageService

    @Autowired
    private lateinit var templateRecommendService: TemplateRecommendService

    @Autowired
    private lateinit var recommendService: TemplateRecommendService

    @Autowired
    private lateinit var userRecordService: UserRecordService

    @Autowired
    private lateinit var channelFreeTemplateMapper: ChannelFreeTemplateMapper

    @Autowired
    private lateinit var channelManagerService: ChannelManagerService

    fun categoryList(type: Int): List<CategoryVo>? = templateCategoryService.list(
        KtQueryWrapper(TemplateCategory::class.java).eq(TemplateCategory::type, type)
            .orderByAsc(TemplateCategory::orderNum)
    ).takeIf { it.isNotEmpty() }?.run {
        map {
            CategoryVo().apply {
                BeanUtil.copyProperties(it, this)
            }
        }
    }

    override fun templateRecommendData(userRecommendSearchDto: UserRecommendSearchDto): Data<List<StatusType>> {
        return Ok("获取我的推荐数据成功", kotlin.run {
            userRecommendSearchDto.status?.run {

                if (userRecommendSearchDto.type == 1) {
                    videoStatusList().find { it.status == this }
                        ?.let {
                            listOf(
                                it.apply {
                                    userRecommendList = templateRecommendPage(userRecommendSearchDto.apply {
                                        status = it.status
                                    })
                                }
                            )
                        } ?: throw Exception("传入正确格式的状态!!!")
                } else {

                    picStatusList().find { it.status == this.plus(4) }?.let {
                        listOf(
                            it.apply {
                                userRecommendList = templateRecommendPage(userRecommendSearchDto.apply {
                                    status = it.status
                                })
                            }
                        )
                    } ?: throw Exception("传入正确格式的状态!!!")
                }

            } ?: kotlin.run {
                if (userRecommendSearchDto.type == 1) {
                    videoStatusList().map {
                        it.apply {
                            userRecommendList = templateRecommendPage(userRecommendSearchDto.apply {
                                status = it.status
                            })
                        }
                    }
                } else {
                    picStatusList().map {
                        it.apply {
                            userRecommendList = templateRecommendPage(userRecommendSearchDto.apply {
                                status = it.status
                            })
                        }
                    }
                }
            }
        })
    }

    override fun removeTemplateRecommend(ids: String): Data<Boolean> =
        Ok("移除成功", templateRecommendService.removeByIds(ids.split(",")))

    val videoStatusList: () -> List<StatusType> = {
        listOf(
            StatusType().apply {
                status = 1
                name = "全部"
            },
            StatusType().apply {
                status = 2
                name = "已通过"
            },
            StatusType().apply {
                status = 3
                name = "待审核"
            },
            StatusType().apply {
                status = 4
                name = "未通过"
            }
        )
    }


    val picStatusList: () -> List<StatusType> = {
        listOf(
            StatusType().apply {
                status = 5
                name = "全部"
            },
            StatusType().apply {
                status = 6
                name = "已通过"
            },
            StatusType().apply {
                status = 7
                name = "待审核"
            },
            StatusType().apply {
                status = 8
                name = "未通过"
            }
        )
    }

    fun templateRecommendPage(userRecommendSearchDto: UserRecommendSearchDto): PageMp<UserRecommendListVo> =
        templateRecommendService.page(Page(userRecommendSearchDto.pageNum ?: 1, userRecommendSearchDto.pageSize ?: 10),
            KtQueryWrapper(TemplateRecommend::class.java)
                .apply {
                    when (userRecommendSearchDto.status) {
                        1 -> {
                            eq(TemplateRecommend::type, 1)
                        }

                        2 -> {
                            eq(TemplateRecommend::type, 1)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.CHECK_PASS.code)
                        }

                        3 -> {
                            eq(TemplateRecommend::type, 1)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.PRE_CHECK.code)
                        }

                        4 -> {
                            eq(TemplateRecommend::type, 1)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.CHECK_FAIL.code)
                        }

                        5 -> {
                            eq(TemplateRecommend::type, 2)
                        }

                        6 -> {
                            eq(TemplateRecommend::type, 2)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.CHECK_PASS.code)
                        }

                        7 -> {
                            eq(TemplateRecommend::type, 2)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.PRE_CHECK.code)
                        }

                        8 -> {
                            eq(TemplateRecommend::type, 2)
                            eq(TemplateRecommend::checkStatus, CheckStatusEnum.CHECK_FAIL.code)
                        }

                        else -> {}
                    }
                    eq(TemplateRecommend::createBy, ProfileHolder.getProfile().id.toLong())
                    orderByDesc(TemplateRecommend::createTime)
                })
            .let { page ->
                Page<UserRecommendListVo>().apply {
                    BeanUtil.copyProperties(page, this)
                    records = page.records.takeIf { it.isNotEmpty() }
                        ?.run {
                            map {
                                UserRecommendListVo().apply {
                                    BeanUtil.copyProperties(it, this)
                                    createDate = it.createTime?.format()
                                }
                            }
                        }
                }.format()
            }

    override fun templatePage(appTemplateSearchDto: AppTemplateSearchDto): Data<TemplateIndex> =
        Ok("获取模板页数据成功", kotlin.run {
            appTemplateSearchDto.categoryId?.let {
                TemplateIndex().apply {
                    templateCategoryService.getById(it)?.let { templateCategory ->
                        templateCategory.type.let { type ->
                            when (type) {
                                1 -> {
                                    videoTemplate = listOf(
                                        CategoryVo().apply {
                                            id = templateCategory.id
                                            name = templateCategory.name
                                            templateList = templatePageByCategory(appTemplateSearchDto, 1)
                                        }
                                    )
                                }

                                else -> {
                                    picTemplate = listOf(
                                        CategoryVo().apply {
                                            id = templateCategory.id
                                            name = templateCategory.name
                                            templateList = templatePageByCategory(appTemplateSearchDto, 2)
                                        }
                                    )
                                }
                            }
                        }
                    }
                }
            } ?: kotlin.run {
                TemplateIndex().apply {
                    categoryList(1)?.run {
                        videoTemplate = map {
                            it.apply {
                                templateList = templatePageByCategory(
                                    appTemplateSearchDto.apply { categoryId = it.id?.toInt() },
                                    1
                                )
                            }
                        }
                    }
                    categoryList(2)?.run {
                        picTemplate = map {
                            it.apply {
                                templateList = templatePageByCategory(
                                    appTemplateSearchDto.apply { categoryId = it.id?.toInt() },
                                    2
                                )
                            }
                        }
                    }
                }
            }
        })

    fun templatePageByCategory(appTemplateSearchDto: AppTemplateSearchDto, type: Int): PageMp<TemplateListVo> =
        templateService.page(
            Page(appTemplateSearchDto.pageNum!!.toLong(), appTemplateSearchDto.pageSize!!.toLong()),
            KtQueryWrapper(Template::class.java).eq(Template::type, type)
                .eq(appTemplateSearchDto.categoryId != null, Template::categoryId, appTemplateSearchDto.categoryId)
                .eq(Template::requestStatus, 1)
                .eq(Template::display, true)
                .orderByDesc(Template::createTime)
        ).let { page ->
            Page<TemplateListVo>().apply {
                BeanUtil.copyProperties(page, this)
                records = page.records.takeIf { it.isNotEmpty() }?.run {
                    map {
                        TemplateListVo().apply {
                            BeanUtil.copyProperties(it, this)
                            appTemplateSearchDto.channelCode?.let { code ->

                                channelManagerService.getOne(
                                    KtQueryWrapper(ChannelManager::class.java)
                                        .eq(ChannelManager::code, code)
                                )
                                    ?.let { channelManager ->
                                        channelFreeTemplateMapper.selectOne(
                                            KtQueryWrapper(ChannelFreeTemplate::class.java)
                                                .eq(ChannelFreeTemplate::channelId, channelManager.id)
                                                .eq(ChannelFreeTemplate::templateId, it.id)
                                                .eq(ChannelFreeTemplate::templateType, it.type)
                                        )
                                            ?.run {
                                                free = true
                                            }
                                    }
                            }
                            when (type) {
                                1 -> videoSubFaces =
                                    it.videoTemplateId?.run { videoTemplateFaceService.getVideoTemplateSubFace(this) }

                                else -> picSubFaces =
                                    it.picTemplateId?.run { picTemplateFaceService.getPicTemplateSubFace(this) }
                            }
                            templateDetail = it.id?.templateDetailApi()
                        }
                    }
                }
            }.format()
        }


    override fun templateDetail(id: Long): Data<TemplateDetailVo> = id.templateDetailApi()?.run {
        Ok("获取资源成功", this)
    } ?: Fail(201, "暂无数据")


    fun Long.templateDetailApi(): TemplateDetailVo? = templateService.getById(this)?.let {
        TemplateDetailVo().apply {
            BeanUtil.copyProperties(it, this)
            appUserService.appUserInfo(it.createBy!!)?.let { userInfo ->
                headUrl = userInfo.headUrl
                username = userInfo.username
            }
            commentNum = templateCommentService.count(
                KtQueryWrapper(TemplateComment::class.java).eq(TemplateComment::templateId, id)
            ).toLong()
            isLike = userCollectService.isLike(ProfileHolder.getProfile().id.toLong(), this@templateDetailApi)
            isCollect = userCollectService.isCollect(ProfileHolder.getProfile().id.toLong(), this@templateDetailApi)
        }
    }

    override fun templateLike(id: Long): Data<Boolean> =
        Ok("操作成功", kotlin.run {
            userCollectService.getOne(
                KtQueryWrapper(UserCollect::class.java).eq(UserCollect::type, 1)
                    .eq(UserCollect::createBy, ProfileHolder.getProfile().id.toLong())
                    .eq(UserCollect::templateId, id)
            )?.run {
                userCollectService.removeById(this.id).takeIf { it }?.run {
                    templateService.getById(id)?.let {
                        templateService.updateById(it.apply {
                            if (likeNum != 0L) {
                                likeNum = likeNum?.minus(1)
                            }
                        })
                    }
                }
            } ?: kotlin.run {
                userCollectService.save(UserCollect().apply {
                    type = 1
                    templateId = id
                    templateType = templateService.getById(id)?.type
                    createBy = ProfileHolder.getProfile().id.toLong()
                }).takeIf { it }?.run {
                    userInteractionMessageService.sendInteractionMessage(UserInteractionMessage().apply {
                        sendUser = ProfileHolder.getProfile().id.toLong()
                        type = MessageTypeEnum.LIKE.code
                        templateId = id
                        createBy = templateService.getById(id)?.createBy
                    })
                    WebSocketServer.sendMessage(templateService.getById(id)?.createBy!!)
                    templateService.getById(id)?.let {
                        templateService.updateById(it.apply {
                            likeNum = likeNum?.plus(1)
                        })
                    }
                }
            }
        })

    override fun templateCollect(id: Long): Data<Boolean> =
        Ok("操作成功", kotlin.run {
            userCollectService.getOne(
                KtQueryWrapper(UserCollect::class.java).eq(UserCollect::type, 2)
                    .eq(UserCollect::createBy, ProfileHolder.getProfile().id.toLong()).eq(UserCollect::templateId, id)
            )?.run {
                userCollectService.removeById(this.id).takeIf { it }?.run {
                    templateService.getById(id)?.let {
                        templateService.updateById(it.apply {
                            if (collectNum != 0L) {
                                collectNum = collectNum?.minus(1)
                            }
                        })
                    }
                }
            } ?: run {
                userCollectService.save(UserCollect().apply {
                    type = 2
                    templateId = id
                    templateType = templateService.getById(id)?.type
                    createBy = ProfileHolder.getProfile().id.toLong()
                }).takeIf { it }?.run {
                    WebSocketServer.sendMessage(templateService.getById(id)?.createBy!!)
                    userInteractionMessageService.sendInteractionMessage(UserInteractionMessage().apply {
                        sendUser = ProfileHolder.getProfile().id.toLong()
                        type = MessageTypeEnum.COLLECT.code
                        templateId = id
                        createBy = templateService.getById(id)?.createBy
                    })

                    templateService.getById(id)?.let {
                        templateService.updateById(it.apply {
                            collectNum = collectNum?.plus(1)
                        })
                    }
                }
            }
        })

    override fun templateComment(appTemplateCommentDto: AppTemplateCommentDto): Data<Boolean> =
        kotlin.run {
            userInteractionMessageService.sendInteractionMessage(UserInteractionMessage().apply {
                sendUser = ProfileHolder.getProfile().id.toLong()
                type = MessageTypeEnum.COMMENT.code
                templateId = appTemplateCommentDto.templateId
                comment = appTemplateCommentDto.content
                createBy = templateService.getById(id)?.createBy
            })
            templateCommentService.saveTemplateComment(TemplateComment().apply {
                BeanUtil.copyProperties(appTemplateCommentDto, this)
            })
        }


    override fun recommendUserRecord(appTemplateRecommendDto: AppTemplateRecommendDto): Data<Boolean> =
        Ok(
            "提交推荐成功", recommendService.save(
                TemplateRecommend().apply {
                    appUserService.appUserInfo(ProfileHolder.getProfile().id.toLong())
                        ?.let {
                            createBy = it.id
                            username = it.username
                            userId = it.userId
                        }
                    userRecordService.getById(appTemplateRecommendDto.userRecordId)?.let {
                        type = it.requestId?.run { 1 } ?: 2
                        userRecordId = it.id
                        categoryId = appTemplateRecommendDto.categoryId
                        title = appTemplateRecommendDto.title
                        cover = appTemplateRecommendDto.cover
                        content = it.url
                    }
                })
        )

    override fun templateCommentPage(templateCommentSearchDto: AppTemplateCommentSearchDto): PageData<AppTemplateCommentVo> =
        templateCommentService.page(Page(
            templateCommentSearchDto.pageNum!!.toLong(),
            templateCommentSearchDto.pageSize!!.toLong()
        ),
            KtQueryWrapper(TemplateComment::class.java)
                .apply {
                    eq(TemplateComment::templateId, templateCommentSearchDto.templateId)
                    eq(TemplateComment::checkStatus, CheckStatusEnum.CHECK_PASS.code)
                    or().eq(TemplateComment::createBy, ProfileHolder.getProfile().id.toLong())
                    orderByDesc(TemplateComment::createTime)
                })
            .let { page ->
                Page<AppTemplateCommentVo>().apply {
                    BeanUtil.copyProperties(page, this)
                    records = page.records.takeIf { it.isNotEmpty() }
                        ?.run {
                            map {
                                AppTemplateCommentVo().apply {
                                    commentId = it.id
                                    content = it.content
                                    createDate = it.createTime?.format()
                                    appUserService.appUserInfo(it.createBy!!)?.let {
                                        username = it.username
                                        headUrl = it.headUrl
                                    }
                                    isAuthor = templateService.getById(it.templateId)?.run { createBy == it.createBy }
                                    isMy = ProfileHolder.getProfile().id?.toLong() == it.createBy
                                }
                            }
                        }
                }.pageInfo()
            }

    override fun templateReport(appTemplateReportDto: AppTemplateReportDto): Data<Boolean> =
        templateReportService.saveTemplateReport(TemplateReport().apply {
            BeanUtil.copyProperties(appTemplateReportDto, this)
        })

    override fun myCollectPage(appTemplateSearchDto: AppTemplateSearchDto): Data<PageData<TemplateListVo>> =
        userCollectPage(appTemplateSearchDto)

    fun userCollectPage(appTemplateSearchDto: AppTemplateSearchDto): Data<PageData<TemplateListVo>> {
        return userCollectService.page(
            Page(appTemplateSearchDto.pageNum!!.toLong(), appTemplateSearchDto.pageSize!!.toLong()),
            KtQueryWrapper(UserCollect::class.java)
                .eq(appTemplateSearchDto.categoryId != null, UserCollect::templateType, appTemplateSearchDto.categoryId)
                .eq(UserCollect::type, 2)
                .eq(UserCollect::createBy, ProfileHolder.getProfile().id.toLong())
                .orderByDesc(UserCollect::createTime)
        ).let { page ->
            Ok("获取收藏数据成功", Page<TemplateListVo>().apply {
                BeanUtil.copyProperties(page, this)
                records = page.records.takeIf { it.isNotEmpty() }?.run {
                    map {
                        TemplateListVo().apply {
                            templateService.getById(it.templateId)?.let {
                                BeanUtil.copyProperties(it, this)
                                templateDetail = it.id?.templateDetailApi()
                            }
                        }
                    }
                }
            }.pageInfo())
        }
    }

}